﻿using System;
using System.IO;
using System.Net;

namespace DoNet.Utils
{
    /// <summary>
    /// 文件帮助类
    /// </summary>
    public class FileUtil
    {
        /// <summary>
        /// 获取URL连接中的文件名称
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string GetUrlFileName(string url)
        {
            Uri uri = new Uri(url);
            string filename = Path.GetFileName(uri.LocalPath);
            return filename;
        }

        /// <summary>
        /// 根据完整文件路径获取FileStream
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static FileStream GetFileStream(string fileName)
        {
            FileStream fileStream = null;
            if (!string.IsNullOrEmpty(fileName) && File.Exists(fileName))
            {
                fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            }
            return fileStream;
        }

        /// <summary>
        /// 从Url下载文件
        /// </summary>
        /// <param name="url"></param>
        /// <param name="fullFilePathAndName"></param>
        public static void DownLoadFileFromUrl(string url, string fullFilePathAndName)
        {
            using (FileStream fs = new FileStream(fullFilePathAndName, FileMode.OpenOrCreate))
            {
                WebClient wc = new WebClient();
                var data = wc.DownloadData(url);
                fs.Write(data, 0, data.Length);
                fs.Flush(true);
            }
        }

        /// <summary>
        /// 保存文件到指定文件夹(根目录下)
        /// </summary>
        /// <param name="bytes">文件内容</param>
        /// <param name="fileName">文件名称（含后缀名）</param>
        /// <param name="dirPath">相对于根目录下文件夹路径</param>
        public static void SaveFile(byte[] bytes, string fileName, string dirPath)
        {
            string savePath = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory) + Path.DirectorySeparatorChar + dirPath;
            //创建文件夹目录
            TryCreateDirectory(savePath);
            //读出到文件名称 才会去保存
            if (!string.IsNullOrWhiteSpace(fileName))
            {
                string filePath = Path.GetDirectoryName(savePath + Path.DirectorySeparatorChar + fileName);
                if (!File.Exists(filePath))
                {
                    using (var fs = File.Open(filePath, FileMode.OpenOrCreate))
                    {
                        fs.Write(bytes, 0, bytes.Length);
                        fs.Flush();
                    }
                }
            }
        }

        /// <summary>
        /// 判断文件是否正在被使用
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <returns></returns>
        public static bool FileInUse(string filePath)
        {
            try
            {
                if (!File.Exists(filePath)) // The path might also be invalid.
                {
                    return false;
                }

                using (FileStream stream = new FileStream(filePath, FileMode.Open))
                {
                    return false;
                }
            }
            catch
            {
                return true;
            }
        }

        /// <summary>
        /// 如果目录不存在，则创建目录
        /// </summary>
        /// <param name="dir">目录绝对路径</param>
        public static void TryCreateDirectory(string dir)
        {
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
        }

        /// <summary>
        /// 从指定的字节流写入文件
        /// </summary>
        /// <param name="destFileName">目标文件名</param>
        /// <param name="bufferWrite">要写入的字节流</param>
        public static void WriteFileFromBuffer(string destFileName, byte[] bufferWrite)
        {
            //写入文件
            using (FileStream fileStream = new FileStream(destFileName, FileMode.Create, FileAccess.ReadWrite))
            {
                //以二进制方式写文件 
                //创建一个二进制数据流写入器，和打开的文件关联
                using (BinaryWriter binaryWriter = new BinaryWriter(fileStream))
                {
                    binaryWriter.Write(bufferWrite);
                    binaryWriter.Flush();
                    binaryWriter.Close();
                }
                fileStream.Close();
            }
        }
        /// <summary>
        /// 文件转bytes
        /// </summary>
        /// <param name="fileName">文件路径（文件全路径）</param>
        /// <param name="isDelete">是否删除文件</param>
        /// <returns></returns>
        public static byte[] FileToBytes(string fileName, bool isDelete = false)
        {
            byte[] bytes = null;
            //打开文件
            using (FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                // 读取文件的 byte[]
                bytes = new byte[fileStream.Length];
                fileStream.Read(bytes, 0, bytes.Length);
            }
            if (isDelete)
            {
                File.Delete(fileName);//删除临时文件
            }
            return bytes;
        }
        /// <summary>
        /// 文件转流
        /// </summary>
        /// <param name="fileName">文件路径（文件全路径）</param>
        /// <param name="isDelete">是否删除文件</param>
        /// <returns></returns>
        public static Stream FileToStream(string fileName, bool isDelete = false)
        {
            Stream stream = null;
            //打开文件
            using (FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                // 读取文件的 byte[]
                byte[] bytes = new byte[fileStream.Length];
                fileStream.Read(bytes, 0, bytes.Length);

                // 把 byte[] 转换成 Stream
                stream = new MemoryStream(bytes);
            }

            if (isDelete)
            {
                File.Delete(fileName);//删除文件
            }
            return stream;
        }

        /// <summary> 
        /// 将 Stream 转成 byte[] 
        /// </summary> 
        public static byte[] StreamToBytes(Stream input)
        {
            byte[] buffer = new byte[16 * 1024];
            using (MemoryStream ms = new MemoryStream())
            {
                int read;
                while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, read);
                }
                input.Position = 0;
                return ms.ToArray();
            }
        }
        /// <summary>
        /// 将 byte[] 转 Stream
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public Stream BytesToStream(byte[] buffer)
        {
            Stream stream = new MemoryStream(buffer);
            stream.Seek(0, SeekOrigin.Begin);
            //设置stream的position为流的开始
            return stream;
        }
    }
}
